package com.mask.token.util;

import com.mask.token.model.MaskUserDetails;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;

/**
 * Mask Security 工具类
 * 提供获取当前登录用户信息的便捷方法
 *
 * @author mask
 * @since 1.0.0
 */
@Slf4j
public class MaskSecurityUtil {

    /**
     * 获取当前认证信息
     *
     * @return 认证信息，如果未认证则返回null
     */
    public static Authentication getCurrentAuthentication() {
        return SecurityContextHolder.getContext().getAuthentication();
    }

    /**
     * 获取当前登录用户详情
     *
     * @return 用户详情，如果未认证则返回null
     */
    public static MaskUserDetails getCurrentUser() {
        Authentication authentication = getCurrentAuthentication();
        if (authentication == null || !authentication.isAuthenticated()) {
            return null;
        }

        Object principal = authentication.getPrincipal();
        if (principal instanceof MaskUserDetails) {
            return (MaskUserDetails) principal;
        }

        log.warn("当前用户不是MaskUserDetails类型: {}", principal.getClass().getName());
        return null;
    }

    /**
     * 获取当前登录用户ID
     *
     * @return 用户ID，如果未认证则返回null
     */
    public static Long getCurrentUserId() {
        MaskUserDetails userDetails = getCurrentUser();
        return userDetails != null ? userDetails.getUserId() : null;
    }

    /**
     * 获取当前登录用户名
     *
     * @return 用户名，如果未认证则返回null
     */
    public static String getCurrentUsername() {
        MaskUserDetails userDetails = getCurrentUser();
        return userDetails != null ? userDetails.getUsername() : null;
    }

    /**
     * 获取当前登录用户邮箱
     *
     * @return 用户邮箱，如果未认证则返回null
     */
    public static String getCurrentUserEmail() {
        MaskUserDetails userDetails = getCurrentUser();
        return userDetails != null ? userDetails.getEmail() : null;
    }

    /**
     * 获取当前登录用户手机号
     *
     * @return 用户手机号，如果未认证则返回null
     */
    public static String getCurrentUserPhone() {
        MaskUserDetails userDetails = getCurrentUser();
        return userDetails != null ? userDetails.getPhone() : null;
    }

    /**
     * 获取当前登录用户昵称
     *
     * @return 用户昵称，如果未认证则返回null
     */
    public static String getCurrentUserNickname() {
        MaskUserDetails userDetails = getCurrentUser();
        return userDetails != null ? userDetails.getNickname() : null;
    }

    /**
     * 获取当前登录用户头像
     *
     * @return 用户头像，如果未认证则返回null
     */
    public static String getCurrentUserAvatar() {
        MaskUserDetails userDetails = getCurrentUser();
        return userDetails != null ? userDetails.getAvatar() : null;
    }

    /**
     * 获取当前登录用户设备ID
     *
     * @return 设备ID，如果未认证则返回null
     */
    public static String getCurrentUserDeviceId() {
        MaskUserDetails userDetails = getCurrentUser();
        return userDetails != null ? userDetails.getDeviceId() : null;
    }

    /**
     * 获取当前登录用户角色
     *
     * @return 用户角色，如果未认证则返回null
     */
    public static String getCurrentUserRole() {
        MaskUserDetails userDetails = getCurrentUser();
        return userDetails != null ? userDetails.getRole() : null;
    }

    /**
     * 获取当前登录用户权限
     *
     * @return 用户权限集合，如果未认证则返回null
     */
    public static java.util.Collection<? extends org.springframework.security.core.GrantedAuthority> getCurrentUserAuthorities() {
        MaskUserDetails userDetails = getCurrentUser();
        return userDetails != null ? userDetails.getAuthorities() : null;
    }

    /**
     * 获取当前登录用户扩展属性
     *
     * @param key 属性键
     * @return 属性值，如果未认证或属性不存在则返回null
     */
    public static Object getCurrentUserAttribute(String key) {
        MaskUserDetails userDetails = getCurrentUser();
        return userDetails != null ? userDetails.getAttribute(key) : null;
    }

    /**
     * 检查当前用户是否已认证
     *
     * @return 是否已认证
     */
    public static boolean isAuthenticated() {
        Authentication authentication = getCurrentAuthentication();
        return authentication != null && authentication.isAuthenticated();
    }

    /**
     * 检查当前用户是否具有指定角色
     *
     * @param role 角色名称
     * @return 是否具有该角色
     */
    public static boolean hasRole(String role) {
        if (!isAuthenticated()) {
            return false;
        }

        java.util.Collection<? extends org.springframework.security.core.GrantedAuthority> authorities = getCurrentUserAuthorities();
        if (authorities == null) {
            return false;
        }

        String roleWithPrefix = role.startsWith("ROLE_") ? role : "ROLE_" + role;
        return authorities.stream()
                .anyMatch(authority -> roleWithPrefix.equals(authority.getAuthority()));
    }

    /**
     * 检查当前用户是否具有指定权限
     *
     * @param permission 权限名称
     * @return 是否具有该权限
     */
    public static boolean hasPermission(String permission) {
        if (!isAuthenticated()) {
            return false;
        }

        java.util.Collection<? extends org.springframework.security.core.GrantedAuthority> authorities = getCurrentUserAuthorities();
        if (authorities == null) {
            return false;
        }

        return authorities.stream()
                .anyMatch(authority -> permission.equals(authority.getAuthority()));
    }

    /**
     * 检查当前用户是否具有任意一个指定角色
     *
     * @param roles 角色名称数组
     * @return 是否具有任意一个角色
     */
    public static boolean hasAnyRole(String... roles) {
        if (!isAuthenticated() || roles == null || roles.length == 0) {
            return false;
        }

        for (String role : roles) {
            if (hasRole(role)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 检查当前用户是否具有任意一个指定权限
     *
     * @param permissions 权限名称数组
     * @return 是否具有任意一个权限
     */
    public static boolean hasAnyPermission(String... permissions) {
        if (!isAuthenticated() || permissions == null || permissions.length == 0) {
            return false;
        }

        for (String permission : permissions) {
            if (hasPermission(permission)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取当前用户的所有角色
     *
     * @return 角色名称列表，如果未认证则返回空列表
     */
    public static java.util.List<String> getCurrentUserRoles() {
        java.util.Collection<? extends org.springframework.security.core.GrantedAuthority> authorities = getCurrentUserAuthorities();
        if (authorities == null) {
            return new java.util.ArrayList<>();
        }

        return authorities.stream()
                .map(org.springframework.security.core.GrantedAuthority::getAuthority)
                .filter(authority -> authority.startsWith("ROLE_"))
                .map(authority -> authority.substring(5)) // 移除 "ROLE_" 前缀
                .collect(java.util.stream.Collectors.toList());
    }

    /**
     * 获取当前用户的所有权限
     *
     * @return 权限名称列表，如果未认证则返回空列表
     */
    public static java.util.List<String> getCurrentUserPermissions() {
        java.util.Collection<? extends org.springframework.security.core.GrantedAuthority> authorities = getCurrentUserAuthorities();
        if (authorities == null) {
            return new java.util.ArrayList<>();
        }

        return authorities.stream()
                .map(org.springframework.security.core.GrantedAuthority::getAuthority)
                .filter(authority -> !authority.startsWith("ROLE_"))
                .collect(java.util.stream.Collectors.toList());
    }

    /**
     * 获取当前用户登录时间
     *
     * @return 登录时间，如果未认证则返回null
     */
    public static java.time.Instant getCurrentUserLoginTime() {
        MaskUserDetails userDetails = getCurrentUser();
        return userDetails != null ? userDetails.getLoginTime() : null;
    }

    /**
     * 获取当前用户最后活跃时间
     *
     * @return 最后活跃时间，如果未认证则返回null
     */
    public static java.time.Instant getCurrentUserLastActiveTime() {
        MaskUserDetails userDetails = getCurrentUser();
        return userDetails != null ? userDetails.getLastActiveTime() : null;
    }

    /**
     * 更新当前用户最后活跃时间
     */
    public static void updateCurrentUserLastActiveTime() {
        MaskUserDetails userDetails = getCurrentUser();
        if (userDetails != null) {
            userDetails.updateLastActiveTime();
        }
    }
}
